﻿using System;
using System.IO;

class Program
{
    static void Main()
    {
        Console.WriteLine("当前插入的U盘有：");
        string[] drives = Directory.GetLogicalDrives();
        foreach (string drive in drives)
        {
            DriveInfo driveInfo = new DriveInfo(drive);
            if (driveInfo.DriveType == DriveType.Removable)
            {
                Console.WriteLine($"{drive} {driveInfo.VolumeLabel} ({driveInfo.TotalSize / (1024 * 1024 * 1024)}G)");
                /*
                Console.WriteLine(drive);
                Console.WriteLine($"盘符: {driveInfo.Name}");
                Console.WriteLine($" {driveInfo.VolumeLabel}");
                Console.WriteLine($"({driveInfo.TotalSize / (1024 * 1024 * 1024)})G");
                Console.WriteLine($"可用空间: {driveInfo.TotalFreeSpace / (1024 * 1024)} MB");
                Console.WriteLine($"剩余空间: {driveInfo.AvailableFreeSpace / (1024 * 1024)} MB");
                */
            }
        }

        Console.WriteLine("请输入要弹出的U盘盘符：");
        string driveLetter = Console.ReadLine();

        EjectDrive(driveLetter);

        Console.WriteLine("U盘已弹出。");
        Console.ReadLine();
    }

    static void EjectDrive(string driveLetter)
    {
        string path = "\\\\.\\" + driveLetter + ":";
        IntPtr handle = CreateFile(path, GENERIC_READ | GENERIC_WRITE, 0, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
        if (handle != new IntPtr(-1))
        {
            DeviceIoControl(handle, IOCTL_STORAGE_EJECT_MEDIA, IntPtr.Zero, 0, IntPtr.Zero, 0, out uint bytesReturned, IntPtr.Zero);
            CloseHandle(handle);
        }
    }

    const uint GENERIC_READ = 0x80000000;
    const uint GENERIC_WRITE = 0x40000000;
    const uint OPEN_EXISTING = 3;
    const uint IOCTL_STORAGE_EJECT_MEDIA = 0x2D4808;

    const uint INVALID_HANDLE_VALUE = 0xFFFFFFFF;

    [System.Runtime.InteropServices.DllImport("kernel32.dll", SetLastError = true)]
    static extern IntPtr CreateFile(string lpFileName, uint dwDesiredAccess, uint dwShareMode, IntPtr lpSecurityAttributes, uint dwCreationDisposition, uint dwFlagsAndAttributes, IntPtr hTemplateFile);

    [System.Runtime.InteropServices.DllImport("kernel32.dll", SetLastError = true)]
    static extern bool DeviceIoControl(IntPtr hDevice, uint dwIoControlCode, IntPtr lpInBuffer, uint nInBufferSize, IntPtr lpOutBuffer, uint nOutBufferSize, out uint lpBytesReturned, IntPtr lpOverlapped);

    [System.Runtime.InteropServices.DllImport("kernel32.dll", SetLastError = true)]
    static extern bool CloseHandle(IntPtr hObject);
}

